package com.zd.lib.demo;

import android.text.TextUtils;

import com.zd.lib.http.okhttp.ProgressListener;
import com.zd.lib.http.okhttp.ProgressRequestInterceptor;
import com.zd.lib.http.okhttp.ProgressResponseInterceptor;
import com.zd.lib.http.retrofit.RetrofitUtils;
import com.zd.lib.http.retrofit.utils.SchedulerCompat;
import com.zd.lib.utils.LogUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.Url;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by zoudong on 16/7/6.
 */
public class FileApi {
    private static FileApi ourInstance = new FileApi();

    public static FileApi getInstance() {
        return ourInstance;
    }
   public static final int TIMEOUT=20;
    private FileApi() {

    }

    private String baseUrl="http://imgup.xin.com/upload.php/";

    public Observable<ResponseBody> ImageUpload(String filepath, final ProgressListener progressListener) {

        OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new ProgressRequestInterceptor(progressListener)).connectTimeout(TIMEOUT, TimeUnit.SECONDS).build();
        Retrofit retrofit = RetrofitUtils.getDefaultRetrofit(baseUrl,okHttpClient);
        Upload upload =retrofit.create(Upload.class);
        Map<String, RequestBody> param = new HashMap<>();
        File file = new File(filepath);
        param.put("app", MultipartBody.create(MultipartBody.FORM, "xin_app"));
        param.put("key", MultipartBody.create(MultipartBody.FORM, "RdUAb6GF6uWjqW"));
        RequestBody requestBody = MultipartBody.create(MultipartBody.FORM, file);
        param.put("pic\"; filename=\"*", requestBody);
        return  upload.uploadImage(param)
                .compose(SchedulerCompat.<ResponseBody>applyIoSchedulers())   //在 doOnSubscribe()的后面跟一个 subscribeOn() ，就能指定准备工作的线程了。
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

    }

//    http://app.youxinpai.com/xin/android-seller/m_seller.apk



    public Observable<ResponseBody> downloadFile(String filename, final ProgressListener progressListener) {

        OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new ProgressResponseInterceptor(progressListener)).connectTimeout(TIMEOUT, TimeUnit.SECONDS).build();
        Retrofit retrofit = RetrofitUtils.getDefaultRetrofit(baseUrl, okHttpClient);
        Upload upload = retrofit.create(Upload.class);
        return upload.loadFile(filename)
                .compose(SchedulerCompat.<ResponseBody>applyNewSchedulers());   //在 doOnSubscribe()的后面跟一个 subscribeOn() ，就能指定准备工作的线程了。
    }
    public Observable<String> downloadFile(final String url, final String filename){
        return downloadFile(url,filename,null);
    }


    public Observable<String> downloadFile(final String url, final String filename, final ProgressListener progressListener) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (progressListener != null) {
            builder.addInterceptor(new ProgressResponseInterceptor(progressListener));
        }
        builder.connectTimeout(TIMEOUT, TimeUnit.SECONDS).build();

        Retrofit retrofit = RetrofitUtils.getDefaultRetrofit(baseUrl, builder.build());
        final Upload upload = retrofit.create(Upload.class);
        Observable<String> observable;
        File file = new File(filename);
        if (file.exists() && file.getTotalSpace() > 10) { //判断大小 异常处理 文件下载成功
            observable = Observable.create(new Observable.OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext(filename);
                    subscriber.onCompleted();
                }
            });
        } else {
            observable = upload.downloadFile(url).map(new Func1<ResponseBody, String>() {
                @Override
                public String call(ResponseBody responseBody) {
                    boolean b = writeResponseBodyToDisk(filename, responseBody);
                    if (!b) {
                        File file = new File(url);
                        if (file.exists()) {
                            file.delete();
                        }
                        return null;
                    }
                    return filename;
                }
            }).flatMap(new Func1<String, Observable<String>>() {
                @Override
                public Observable<String> call(String s) {
                    if (TextUtils.isEmpty(s)) {
                        return Observable.error(new FileNotFoundException("下载失败"));
                    }
                    return Observable.just(s);
                }
            });
        }
        return observable;
    }


    public interface Upload {
        @Multipart
        @POST("http://imgup.xin.com/upload.php")
        Observable<ResponseBody> uploadImage(@PartMap Map<String, RequestBody> param);

        @Multipart
        @POST("http://upload.xin.com/upload_file.php")
        Observable<ResponseBody> uploadFile(@PartMap Map<String, RequestBody> param);

         @GET("http://app.youxinpai.com/xin/android-seller/{filename}")
        Observable<ResponseBody> loadFile(@Path("filename") String  filename);
        @GET
        Observable<ResponseBody> downloadFile(@Url String url);
    }
    private boolean writeResponseBodyToDisk(String fileName,ResponseBody body) {
        try {
            File futureStudioIconFile = new File(fileName);
            if (!futureStudioIconFile.getParentFile().exists()) {
                futureStudioIconFile.mkdirs();
            }
            InputStream inputStream = null;
            OutputStream outputStream = null;
            try {
                byte[] fileReader = new byte[4096];
                long fileSize = body.contentLength();
                long fileSizeDownloaded = 0;
                inputStream = body.byteStream();
                outputStream = new FileOutputStream(futureStudioIconFile);
                while (true) {
                    int read = inputStream.read(fileReader);
                    if (read == -1) {
                        break;
                    }
                    outputStream.write(fileReader, 0, read);
                    fileSizeDownloaded += read;
                    LogUtils.d("download", "file download: " + fileSizeDownloaded + " of " + fileSize);
                }
                outputStream.flush();
                return true;
            } catch (IOException e) {
                LogUtils.e("zoudong", "writeResponseBodyToDisk: "+e.toString());
                return false;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }

                if (outputStream != null) {
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            return false;
        }
    }

}
